# -*- coding:utf-8 -*-

# login,submit,result应该是一个原子操作，也就是说这个程序
# 不是线程安全的，因为获取结果是通过抓取status页面的第一条
# 记录，必须保证在抓下当前记录后才可以进行下一次的登录提交

import requests
import bs4
import os
import re
import sys
import logging
import time

urlHome = 'http://poj.org'
urlLogin = 'http://poj.org/login'
urlSubmit = 'http://poj.org/submit'
urlStatus = 'http://poj.org/status'
dictLanguage = {
	'G++':'0', 'GCC':'1', 'JAVA':'2', 
	'PASCAL':'3', 'C++':'4', 'C':'5',
	'FORTRAN':'6' }
listStatus = [
	'Run ID', 'User', 'Problem', 'Result',
	'Memory', 'Time', 'Language', 'Code Length',
	'Submit Time' ]
dictError = { 
	0:u'get page error', -1:u'Waiting', 
	-2:u'Compiling', -3:u'Running & Judging' }

def createSrcInfo():
	return '/*\n' + ' * ' + time.ctime()+'\n' + ' * submitted by py_spider\n' + ' */\n'

def initLogging():
	logging.basicConfig(level=logging.INFO, format='<--- %(message)s --->')

def initSession():
	return requests.session()

def login(session, user_id, passwd):
	loginData = {'user_id1':user_id, 'password1':passwd, 'B1':'login', 'url':'/'}
	logging.info('login...')
	try:
		session.post(urlLogin, loginData)
	except:
		logging.info('login failed')
		return False
	logging.info('login succeed')
	return True

def submit(session, pid, lang, src):
	submitData = {
		'problem_id':pid, 'language':dictLanguage[lang], 
		'source':src, 'submit':'Submit'
	}
	logging.info('submit...')
	try:
		session.post(urlSubmit, submitData)
	except:
		logging.info('submit failed')
		return False
	logging.info('submit succeed')
	return True

# 每隔1秒去刷新一次status页面来获取结果
def getResults(session, statusData):
	try: #抓取页面
		response = session.get(urlStatus, params=statusData)
		page = response.content
	except: #抓取页面出错
		return 0, None
	bs = bs4.BeautifulSoup(page)
	table = bs.html.body.find('table', cellspacing='0')
	tr = table.find('tr', align='center') #返回第一条匹配的tr标签
	results = list(tr.strings)
	for key in dictError:
		if dictError[key] == results[3]:
			return key, None
	else: return 1, results

def getStatus(session, user_id):
	statusData = { 'user_id':user_id }
	logging.info('get status')
	while True:
		res, results = getResults(session, statusData)
		if res <= 0: 
			logging.info(dictError[res])
			time.sleep(1)
		else:
			for i in range(9):
				print listStatus[i],':',results[i]
			break
	logging.info('get status succeed')
	return True

def main():
	if len(sys.argv) != 6:
		user_id = 'gvj0'
		passwd = 'gvj2014'
		pid = '1000'
		lang = 'G++'
		srcFile = open('1000.cpp', 'r')
		src = createSrcInfo() + srcFile.read()
		srcFile.close()
	else:
		user_id = sys.argv[1]
		passwd = sys.argv[2]
		pid = sys.argv[3]
		lang = sys.argv[4]
		srcFileName = sys.argv[5]
		srcFile = open(srcFileName, 'r')
		src = createSrcInfo() + srcFile.read()
		srcFile.close()

	initLogging()
	session = initSession()
	if login(session, user_id, passwd) == False: return
	if submit(session, pid, lang, src) == False: return
	if getStatus(session, user_id) == False: return

if __name__ == '__main__':
	for i in range(10):
		main()
